package edu.sc.seis.fissuresUtil.xml;

import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import edu.iris.Fissures.IfSeismogramDC.DataCenterOperations;
import edu.iris.Fissures.IfSeismogramDC.RequestFilter;
import edu.iris.Fissures.model.MicroSecondDate;
import edu.iris.Fissures.seismogramDC.LocalSeismogramImpl;
import edu.sc.seis.fissuresUtil.chooser.ClockUtil;
import edu.sc.seis.fissuresUtil.database.DBDataCenter;
import edu.sc.seis.fissuresUtil.database.LocalDataCenterCallBack;
import edu.sc.seis.fissuresUtil.time.CoverageTool;

/**
 * DataSetSeismogram.java Created: Tue Feb 11 10:08:37 2003
 * 
 * @author <a href="mailto:">Srinivasa Telukutla </a>
 * @version
 */
public class DCDataSetSeismogram extends DataSetSeismogram implements
        LocalDataCenterCallBack, Cloneable {

    /**
     * Creates a DCDataSetSeismogram without a containing dataset and without a
     * name. The dataset should be automagically set when this is added and the
     * name will be autogenerated if needed.
     */
    public DCDataSetSeismogram(RequestFilter rf, DataCenterOperations dco) {
        this(rf, dco, null);
    }

    public DCDataSetSeismogram(RequestFilter rf, DataCenterOperations dco,
            DataSet ds) {
        this(rf, dco, ds, null);
    }

    public DCDataSetSeismogram(RequestFilter rf, DataCenterOperations dco,
            DataSet ds, String name) {
        super(ds, name);
        this.requestFilter = rf;
        this.dataCenterOps = dco;
    }

    public void retrieveData(SeisDataChangeListener dataListener) {
        List existingSeismos = new ArrayList();
        synchronized(seisCache) {
            Iterator it = seisCache.iterator();
            while(it.hasNext()) {
                LocalSeismogramImpl current = (LocalSeismogramImpl)((SoftReference)it.next()).get();
                if(current != null) {
                    if(intersects(requestFilter, current)) {
                        existingSeismos.add(current);
                    } else {
                        it.remove();
                    }
                }
            }
        }
        RequestFilter[] uncovered = {requestFilter};
        if(existingSeismos.size() > 0) {
            LocalSeismogramImpl[] cachedSeismos = new LocalSeismogramImpl[existingSeismos.size()];
            cachedSeismos = (LocalSeismogramImpl[])existingSeismos.toArray(cachedSeismos);
            pushData(cachedSeismos, dataListener);
            uncovered = CoverageTool.notCovered(uncovered, cachedSeismos);
        }
        if(this.dataCenterOps instanceof DBDataCenter && uncovered.length > 0) {
            ((DBDataCenter)this.dataCenterOps).request_seismograms(uncovered,
                                                                   this,
                                                                   dataListener,
                                                                   false,
                                                                   ClockUtil.now()
                                                                           .getFissuresTime());
        } else {
            finished(dataListener);
        }
    }

    public static boolean intersects(RequestFilter rf, LocalSeismogramImpl seis) {
        MicroSecondDate rfBegin = new MicroSecondDate(rf.start_time);
        MicroSecondDate rfEnd = new MicroSecondDate(rf.end_time);
        if((seis.getBeginTime().before(rfEnd) && seis.getEndTime()
                .after(rfBegin))
                || (seis.getEndTime().after(rfBegin) && seis.getBeginTime()
                        .before(rfEnd))) { return true; }
        return false;
    }

    private DataCenterOperations dataCenterOps;

    private static Logger logger = LoggerFactory.getLogger(DCDataSetSeismogram.class.getName());
}// DataSetSeismogram
